#ifndef PHOTOBOOK_H
#define PHOTOBOOK_H
#include <gtkmm-2.4/gtkmm.h>
#include <glibmm-2.4/glibmm.h>
#include <gdkmm-2.4/gdkmm.h>
#include <gdkmm-2.4/gdkmm/pixbuf.h>
#include <iostream>
#include <deque>
#include <string>
#include <cmath>
#include "catImage.cpp"

class photoBook : public Gtk::Window
{
protected:
	deque<catImage> imageList;
	Gtk::Button nextButton;
	Gtk::Button backButton;
	Gtk::Table listTable;
	Gtk::HBox buttonBox;
	Gtk::VBox windowBox;
	int pageNumber;
	int rows;
	int cols;
	bool zoomed;
	int mpages;
	deque<Gtk::Image*>tv;
	int cindex;
	deque<Gtk::EventBox*> eb;

	//takes all of the images in the imageList
	//and gets 128x128 thumbnails of them
	//then arranges them into a nice little table.
	//
	//all of the Gtk::Images and the Gtk::EventBoxes are
	//dynamically allocated, and stored in deques for easy
	//deletion later on
	void populateTable()
	{
		listTable.set_size_request((148*(cols))+20,(148*(rows))+20);
		int pivot = pageNumber*(rows*cols);
		int counter=pivot;
		register int c2=0;
		for(int x=0;x<rows && counter<imageList.size()-1;x++)
		{
			for(int y=0;y<cols && counter < imageList.size()-1;y++)
			{
				eb.push_back(new Gtk::EventBox);
				eb[c2]->set_events(Gdk::BUTTON_PRESS_MASK);
				eb[c2]->signal_button_press_event()
						.connect(
						sigc::bind<int>(
						sigc::mem_fun(*this,
						&photoBook::ciReturnFunc),
						counter));

				imageList[counter].fitInto(128,128);
				tv.push_back(new Gtk::Image(imageList[counter].
							getScaledInstance()));

				eb[c2]->add(*(tv[c2]));
				
				listTable.attach(*eb[c2],
						guint(y),
						guint(y+1),
						guint(x),
						guint(x+1),
						Gtk::FILL,
						Gtk::FILL,
						guint(10),
						guint(10));

				eb[c2]->show();
				tv[c2]->show();
				cout<<"added image: "<<counter<<endl;
				counter++;
				c2++;
			}
		}
	}

	void clearTable()
	{
		for(int x=0;x<eb.size();x++)
		{
			listTable.remove(*eb[x]);
			delete eb[x];
			delete tv[x];
		}
		eb.clear();
		tv.clear();
		cout<<"cleared table"<<endl;
	}

	void pageNext()
	{
		clearTable();
		if(++pageNumber>mpages-1)
			pageNumber=0;
		populateTable();
	}

	void pageBack()
	{
		clearTable();
		if(--pageNumber<0)
			pageNumber=mpages-1;
		populateTable();
	}

	bool ciReturnFunc(GdkEventButton *event, int cnum)
	{
		if(cnum < imageList.size() && cnum >= 0)
		{
			cindex = cnum;
		}
		else
		{
			cindex = 0;
			cerr<<"got an unexpected cnum value "<<cnum<<endl;
		}
		this->hide();
		return true;
	}

	

public:

	const static short IMAGE_SELECTION_CANCEL = -1;

	photoBook(deque<catImage> iL, int nrows=3, int ncols=3, int selImg=0) :
		nextButton("Next Page"),
		backButton("Previous Page"),
		rows(nrows),
		cols(ncols),
		pageNumber(0),
		listTable(nrows,ncols,true),
		cindex(-1)
	{
		imageList = iL;

		listTable.set_col_spacings(guint(10));
		listTable.set_row_spacings(guint(10));
		mpages = (int)ceil((float)iL.size()/(float)(nrows*ncols));
		pageNumber = selImg/(nrows*ncols);
		cout<<"starting on page "<<pageNumber<<" of "<<mpages<<endl;

		backButton.signal_clicked().connect(sigc::mem_fun(*this,
					&photoBook::pageBack));

		nextButton.signal_clicked().connect(sigc::mem_fun(
					*this,&photoBook::pageNext));
		add(windowBox);

		buttonBox.pack_start(backButton,Gtk::PACK_SHRINK,5);
		buttonBox.pack_start(nextButton,Gtk::PACK_SHRINK,5);
		windowBox.pack_start(listTable,Gtk::PACK_EXPAND_WIDGET,5);
		windowBox.pack_start(buttonBox,Gtk::PACK_SHRINK,5);


		populateTable();
		backButton.show();
		nextButton.show();
		buttonBox.show();
		listTable.show();
		windowBox.show();
	}

	virtual ~photoBook()
	{
		clearTable();
		cout<<"running photobook destructor"<<endl;
	}

	short run()
	{
		this->show();
		return (short)cindex;
	}

	void clt()
	{
		clearTable();
	}

	void rs()
	{
		populateTable();
	}
};
#endif//PHOTOBOOK_H
